// @ts-nocheck
import styles from "./index.module.less"
import { make } from "../../utils/dom"
import { IconLoader } from "@codexteam/icons"
import { uploadDoc, getDoc } from "./api"

class DocParser {
    static get toolbox() {
        return {
            title: "DocParser",
            icon: `<svg width="800px" height="800px" viewBox="0 0 512 512" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <g id="file__x2C__doc__x2C__word__x2C__document__x2C_">
        <g id="Layer_116">
        <g>
        <g>
        <polygon points="107.071,25.467 349.079,25.467 420.601,97.709       420.601,447.742 107.071,447.742     " style="fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;"/>
        <path d="M420.601,454.602H107.071c-3.79,0-6.859-3.068-6.859-6.859V25.467c0-3.79,3.069-6.86,6.859-6.86      h242.008c1.831,0,3.583,0.729,4.877,2.033l71.522,72.242c1.271,1.285,1.986,3.02,1.986,4.827v350.033      C427.465,451.533,424.391,454.602,420.601,454.602z M113.932,440.883h299.813V100.531L346.22,32.327H113.932V440.883z" style="fill:#4C8CF9;"/>
        </g>
        <g>
        <rect height="105.6" style="fill-rule:evenodd;clip-rule:evenodd;fill:#4C8CF9;" width="313.532" x="129.98" y="177.615"/>
        </g>
        <g>
        <path d="M213.358,258.326h-11.056v-9.818h11.056V258.326z M224.679,258.326v-55.961h19.047      c6.793,0,12.387,2.157,16.782,6.594c4.394,4.304,6.523,9.953,6.523,16.817v9.278c0,6.864-2.13,12.513-6.523,16.821      c-4.396,4.305-9.989,6.451-16.782,6.451H224.679z M235.868,211.111v38.608h7.326c3.994,0,7.057-1.345,9.322-4.038      c2.264-2.689,3.464-6.318,3.464-10.627v-9.416c0-4.304-1.2-7.8-3.464-10.489c-2.265-2.689-5.328-4.038-9.322-4.038H235.868z       M320.441,235.458c0,6.864-2.262,12.513-6.524,16.95c-4.263,4.579-9.856,6.727-16.785,6.727c-6.791,0-12.385-2.148-16.647-6.727      c-4.258-4.437-6.392-10.085-6.392-16.95v-10.086c0-6.864,2.134-12.508,6.392-17.087c4.263-4.438,9.856-6.727,16.647-6.727      c6.796,0,12.522,2.29,16.785,6.727c4.263,4.579,6.524,10.223,6.524,17.087V235.458z M309.255,225.234      c0-4.437-1.064-7.938-3.193-10.76c-2.134-2.822-5.194-4.171-8.93-4.171c-3.859,0-6.791,1.349-8.787,4.171      c-2.134,2.822-3.198,6.323-3.198,10.76v10.224c0,4.441,1.064,8.076,3.198,10.902c2.134,2.689,5.062,4.167,8.787,4.167      c3.863,0,6.796-1.478,8.93-4.167c2.129-2.827,3.193-6.461,3.193-10.902V225.234z M370.925,239.229l0.129,0.266      c0,6.057-1.73,10.765-5.461,14.395c-3.863,3.5-9.058,5.245-15.711,5.245c-6.663,0-11.99-2.148-16.253-6.452      c-4.13-4.309-6.259-9.957-6.259-16.684v-11.169c0-6.727,2.129-12.371,6.126-16.679c4.13-4.304,9.324-6.594,15.849-6.594      c6.925,0,12.256,1.753,16.12,5.387c3.858,3.496,5.727,8.337,5.589,14.527v0.266h-10.921c0-3.762-0.799-6.589-2.528-8.475      c-1.868-2.015-4.529-2.96-8.26-2.96c-3.326,0-5.992,1.349-7.86,4.038c-1.996,2.689-2.927,6.186-2.927,10.489v11.031      c0,4.304,0.931,7.805,3.064,10.627c1.996,2.693,4.791,4.038,8.26,4.038c3.46,0,6.121-0.941,7.723-2.827      c1.729-1.881,2.528-4.708,2.528-8.471H370.925z" style="fill:#FEFEFE;"/>
        </g>
        <g>
        <path d="M263.498,146.357c-14.012,0-26.189-5.08-32.584-13.591c-2.275-3.028-1.666-7.328,1.365-9.604      c3.028-2.285,7.328-1.666,9.606,1.363c3.76,5.006,12.038,8.113,21.612,8.113c0.004,0,0.009,0,0.018,0      c9.691-0.005,18.639-3.263,22.269-8.108c2.276-3.033,6.575-3.644,9.604-1.372c3.032,2.271,3.647,6.571,1.376,9.604      c-6.286,8.379-19.02,13.591-33.239,13.596C263.516,146.357,263.507,146.357,263.498,146.357z" style="fill:#4C8CF9;"/>
        </g>
        
        <g>
        
        <path d="M143.968,233.173c-0.025,0-0.051,0-0.078,0c-41.685-0.455-66.41-11.325-73.49-32.308      c-9.211-27.307,17.035-62.661,32.457-74.669c2.992-2.322,7.303-1.785,9.627,1.198c2.329,2.991,1.792,7.3-1.198,9.631      c-13.25,10.315-34.504,39.829-27.885,59.454c6.245,18.51,36.424,22.709,60.64,22.975c3.788,0.041,6.826,3.147,6.784,6.933      C150.784,230.149,147.722,233.173,143.968,233.173z" style="fill:#4C8CF9;"/>
        
        </g>
        
        <g>
        
        <polygon points="349.079,97.709 420.601,97.709 349.079,25.467           " style="fill-rule:evenodd;clip-rule:evenodd;fill:#D4E4FF;"/>
        
        <path d="M420.601,104.569h-71.521c-3.79,0-6.86-3.07-6.86-6.86V25.467c0-2.781,1.68-5.286,4.249-6.346      c2.579-1.056,5.534-0.455,7.488,1.519l71.522,72.242c1.95,1.969,2.519,4.914,1.454,7.47      C425.868,102.908,423.372,104.569,420.601,104.569z M355.938,90.85h48.217l-48.217-48.703V90.85z" style="fill:#4C8CF9;"/>
        
        </g>
        
        <g>
        
        <path d="M239.339,493.393c-0.376,0-0.757-0.027-1.143-0.092l-22.509-3.766      c-3.306-0.557-5.727-3.414-5.727-6.77v-35.023c0-3.789,3.069-6.859,6.859-6.859c3.791,0,6.86,3.07,6.86,6.859v29.215      l16.782,2.809c3.738,0.629,6.259,4.162,5.633,7.9C245.536,491.021,242.629,493.393,239.339,493.393z" style="fill:#4C8CF9;"/>
        
        </g>
        
        <g>
        
        <path d="M325.25,493.393c-0.376,0-0.762-0.027-1.146-0.092l-22.507-3.766      c-3.309-0.557-5.727-3.414-5.727-6.77v-35.023c0-3.789,3.069-6.859,6.859-6.859s6.86,3.07,6.86,6.859v29.215l16.78,2.809      c3.739,0.629,6.259,4.162,5.635,7.9C331.445,491.021,328.536,493.393,325.25,493.393z" style="fill:#4C8CF9;"/>
        
        </g>
        
        <g>
        
        <path d="M290.873,65.149c6.259-1.744,13.188,0.945,16.519,6.865      c4.13,7.13,1.73,16.143-5.332,20.18c-7.057,4.167-15.978,1.744-19.979-5.382c-3.193-5.52-2.396-12.375,1.469-16.95      c1.331,1.748,3.726,2.285,5.727,1.207C291.276,69.862,292.075,67.168,290.873,65.149L290.873,65.149z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#4C8CF9;"/>
        
        </g>
        
        <g>
        
        <path d="M228.808,65.149c6.259-1.744,13.185,0.945,16.65,6.865      c3.994,7.13,1.597,16.143-5.463,20.18c-6.924,4.167-15.982,1.744-19.979-5.382c-3.196-5.52-2.397-12.375,1.466-16.95      c1.331,1.748,3.861,2.285,5.727,1.207C229.34,69.862,230.006,67.168,228.808,65.149L228.808,65.149z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#4C8CF9;"/>
        
        </g>
        
        <g>
        
        <path d="M373.72,326.398H164.61c-3.791,0-6.86-3.07-6.86-6.859c0-3.791,3.069-6.861,6.86-6.861h209.11      c3.79,0,6.859,3.07,6.859,6.861C380.579,323.328,377.51,326.398,373.72,326.398z" style="fill:#4C8CF9;"/>
        
        </g>
        
        <g>
        
        <path d="M373.72,361.914H164.61c-3.791,0-6.86-3.07-6.86-6.859c0-3.791,3.069-6.861,6.86-6.861h209.11      c3.79,0,6.859,3.07,6.859,6.861C380.579,358.844,377.51,361.914,373.72,361.914z" style="fill:#4C8CF9;"/>
        
        </g>
        
        <g>
        
        <path d="M300.463,397.563H164.61c-3.791,0-6.86-3.07-6.86-6.859c0-3.791,3.069-6.861,6.86-6.861h135.853      c3.79,0,6.864,3.07,6.864,6.861C307.327,394.492,304.253,397.563,300.463,397.563z" style="fill:#4C8CF9;"/>
        
        </g>
        
        </g>
        
        </g>
        
        </g>
        
        <g id="Layer_1"/>
        
        </svg>`,
        }
    }

    static get isReadOnlySupported() {
        return true
    }

    constructor({ data, api, config, readOnly }) {
        this.data = {
            text: data.text,
        }

        this.api = api

        this.readOnly = readOnly

        this.wrapper = undefined
    }

    render() {
        this.wrapper = make("div", styles["cx-custom-doc"])

        if (this.data && this.data.text) {
        } else {
            // 创建输入框, 按钮
            const controlBox = make("div", styles.controlBox)
            const saveBtn = make("div", styles.saveBtn, { innerText: "上传Word文件" })
            controlBox.append(saveBtn)
            this.wrapper.append(controlBox)

            // 监听编辑和保存事件
            this.api.listeners.on(
                saveBtn,
                "click",
                () => {
                    const uploadFileFn = (cb: (data: any) => void) => {
                        const fileDom = make("input", "", { type: "file" })
                        fileDom.style.display = "none"
                        document.body.append(fileDom)
                        fileDom.click()
                        fileDom.addEventListener("change", async (event: any) => {
                            // 处理文件选择事件
                            const file = event.target.files[0]
                            const data = new FormData()
                            data.set("file", file)
                            cb && cb(data)
                            document.body.removeChild(fileDom)
                        })
                    }
                    uploadFileFn((data) => {
                        // @ts-ignore
                        saveBtn.innerHTML = `${IconLoader} 正在解析中......`
                        saveBtn.style.pointerEvents = "none"
                        uploadDoc(data)
                            .then((res: any) => {
                                const { html, total, docId } = res
                                const text = html || ""

                                // 切换为分页符
                                let curPage = 1
                                let pageText = `下一页(${curPage}/${total})`
                                const pageBtn = make("div", styles.pageBtn, { innerText: pageText })

                                this.update(text, curPage >= total)

                                controlBox.remove()

                                this.api.listeners.on(pageBtn, "click", () => {
                                    getDoc(docId, ++curPage).then((res: any) => {
                                        const { html } = res
                                        const text = html || ""
                                        this.update(text, curPage >= total)
                                        pageText = `下一页(${curPage}/${total})`
                                        pageBtn.innerText = pageText
                                    })
                                })
                                this.wrapper.append(pageBtn)
                            })
                            .catch((err) => {
                                saveBtn.innerHTML = `${IconLoader} 上传失败`
                            })
                    })
                },
                false
            )
        }

        return this.wrapper
    }

    update(text, isDelDoc) {
        const curIdx = this.api.blocks.getCurrentBlockIndex()
        const curBlock = this.api.blocks.getBlockByIndex(curIdx)
        // 将html转化为文档组件
        const blocks = this.convertHtmlToJson(text)

        // 删除当前块
        if (isDelDoc) {
            this.api.blocks.delete(curIdx)
        }

        if (blocks && blocks.length) {
            blocks.forEach((row, i) => {
                this.api.blocks.insert(row.type, row.data, null, curIdx + i, true)
            })
        }
    }

    convertHtmlToJson(html: string) {
        const blocks = []
        const parser = new DOMParser()
        const doc = parser.parseFromString(html, "text/html")
        const processNode = (node: Node) => {
            switch (node.nodeName) {
                case "H1":
                case "H2":
                case "H3":
                case "H4":
                case "H5":
                case "H6":
                    blocks.push({
                        type: "header",
                        data: {
                            text: node.innerHTML,
                            level: parseInt(node.nodeName.charAt(1)),
                        },
                    })
                    break
                case "P":
                    blocks.push({
                        type: "paragraph",
                        data: {
                            text: node.innerHTML,
                        },
                    })
                    break
                case "UL":
                case "OL":
                    const items = Array.from(node.childNodes)
                        .filter((child) => child.nodeName === "LI")
                        .map((li) => li.innerHTML)
                    blocks.push({
                        type: "list",
                        data: {
                            style: node.nodeName === "UL" ? "unordered" : "ordered",
                            items: items.map((v) => ({ content: v })),
                        },
                    })
                    break
                case "TABLE":
                    const rows = Array.from(node.querySelectorAll("tr"))
                    const content = rows.map((row) => Array.from(row.querySelectorAll("th, td")).map((cell) => cell.textContent || ""))
                    blocks.push({
                        type: "table",
                        data: normalizeTableData({
                            withHeadings: rows[0].querySelector("th") !== null,
                            content: content,
                        }),
                    })
                    break
                default:
                    if (node.childNodes) {
                        node.childNodes.forEach(processNode)
                    }
            }
        }

        doc.body.childNodes.forEach(processNode)
        return blocks
    }

    save(blockContent) {
        return this.data
    }

    static get sanitize() {
        return {
            text: true,
        }
    }
}

// 定义表格数据类型
interface TableData {
    withHeadings: boolean
    content: string[][]
}
// 处理表格数据，确保每一行的列数相同
export function normalizeTableData(data: TableData): TableData {
    const maxColumns = Math.max(...data.content.map((row) => row.length))

    const normalizedContent = data.content.map((row) => {
        const normalizedRow = [...row]
        while (normalizedRow.length < maxColumns) {
            normalizedRow.push("")
        }
        return normalizedRow
    })

    return {
        withHeadings: data.withHeadings,
        content: normalizedContent,
    }
}

export default DocParser
